package com.ftg.learn.bus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ftg.learn.bus.VO.UserRidVo;
import com.ftg.learn.bus.VO.UserRoleNameVo;
import com.ftg.learn.bus.entity.LoginUser;
import com.ftg.learn.bus.entity.User;
import com.ftg.learn.bus.mapper.UserMapper;
import com.ftg.learn.bus.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ftg.learn.util.JWTUtil;
import com.ftg.learn.util.ResEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 人员表 服务实现类
 * </p>
 *
 * @author lalala
 * @since 2022-03-07
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    UserMapper userMapper;

    /**
     * 查询全部人员，及其角色
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> showAddRole() {
        return userMapper.showAddRole();
    }

    @Override
    public List<Map<String, Object>> queryAllUsers() {
        return userMapper.queryAllUsers();
    }

    /**
     * 分页查询人员信息及其角色。
     * @param pagination
     * @return
     */
    @Override
    public List<UserRoleNameVo> showUserAndRoleName(Page<UserRoleNameVo> pagination){
        return userMapper.showUserAndRoleName(pagination);
    }

    /**
     * 按名字模糊查询分页功能带角色。
     * @param pagination
     * @return
     */
    @Override
    public List<UserRoleNameVo> pageUserAndRoleNameByName(Page<UserRoleNameVo> pagination,String uname){
        return userMapper.pageUserAndRoleNameByName(pagination,uname);
    }


    /**
     * 人员登录功能   密码MD5
     *
     * @param account
     * @param password
     * @return
     */
    @Override
    public ResEntity logIn(String account, String password,
                           HttpServletRequest request, HttpServletResponse response) {
//        ResEntity re = new ResEntity();

        byte[] bs1 = new byte[0];
        try {
            bs1 = MessageDigest.getInstance("md5").digest(password.getBytes());
            password = new BigInteger(1, bs1).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        queryWrapper.eq("password", password);
        User user = userMapper.selectOne(queryWrapper);
        if (Objects.isNull(user)) {
            return ResEntity.LoginFailure("用户名或密码错误");
        }
        // 存入登录人信息
        LoginUser loginUser = LoginUser.builder()
                .id(user.getUid())
                .name(user.getUname())
                .ip(request.getLocalAddr())
                .build();
        //生成token
        String token = JWTUtil.jeneJsonWebToken(loginUser);
//        request.setAttribute("token",token);
        Cookie cookie = new Cookie("token",token);
        cookie.setPath("/");
        cookie.setMaxAge(7200);
        response.addCookie(cookie);

        Cookie loginUserName = new Cookie("loginusername",user.getUname());
        loginUserName.setPath("/");
        loginUserName.setMaxAge(7200);
        response.addCookie(loginUserName);

        Cookie loginUid = new Cookie("loginUid",String.valueOf(user.getUid()));
        loginUid.setPath("/");
        loginUid.setMaxAge(7200);
        response.addCookie(loginUid);

        return ResEntity.loginOk(token);
    }

    /**
     * 人员的添加-->md5密码加密
     * @param e
     * @return
     */
    @Override
    public boolean insertUser(User e) {
        byte[] bs1 = new byte[0];
        try {
            bs1 = MessageDigest.getInstance("md5").digest(e.getPassword().getBytes());
            e.setPassword(new BigInteger(1, bs1).toString(16));
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("account",e.getAccount());
        User user = userMapper.selectOne(query);
        if(Objects.isNull(user)){
            return this.save(e);
        }
        return false;
    }

    /**
     * 人员修改功能  密码MD5
     * @param e
     * @return
     */
    @Override
    public boolean updateUser(User e) {
        byte[] bs1 = new byte[0];
        try {
            bs1 = MessageDigest.getInstance("md5").digest(e.getPassword().getBytes());
            e.setPassword(new BigInteger(1, bs1).toString(16));
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }
        e.setUpdateTime(LocalDateTime.now());
        return this.updateById(e);
    }

    /**
     * 根据用户的名字进行模糊查询
     * @param name
     * @return
     */
    @Override
    public List<User> showByName(String name){
        return userMapper.showByName(name);
    }

    /**
     * 查某个人具有的角色
     *
     * @param uid
     * @return
     */
    @Override
    public List<Map<String, Object>> showRoleForUserId(Long uid) {
        return userMapper.showRoleForUserId(uid);
    }


    /**
     * Transactional
     * 事务操作 表示当前对所有public修饰的 成功提交 失败回滚
     * <p>
     * 对操作的用户删除角色及添加新角色(只操作一个角色)
     *
     * @param rid
     * @param uid
     * @return
     */
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public boolean roleGroupOne(Long rid, Long uid) {
        userMapper.delRoleForUserId(uid);
        userMapper.saveRoleForUserId(rid, uid);
        return true;
    }


    /**
     * Transactional
     * 事务操作 表示当前对所有public修饰的 成功提交 失败回滚
     * <p>
     * 对操作的用户删除角色及添加新角色(操作多个角色)
     *
     * @param rid
     * @param uid
     * @return
     */
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public boolean roleGroup(List<Long> rid, Long uid) {
        userMapper.delRoleForUserId(uid);
        for (Long l : rid) {
            userMapper.saveRoleForUserId(l, uid);
        }
        return true;
    }



    /**
     * 批量删除用户，并同时删除其在用户-角色关联表里的数据。
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = SQLException.class)
    public boolean deleteIdsAndRole(List<Serializable> ids){
        this.removeBatchByIds(ids);
        for (Serializable l : ids){
            userMapper.delRoleForUserId(l);
        }
        return true;
    }

    /**
     * 添加人员，并同时添加其角色。
     *
     * @param  userRidVo
     * @return
     */
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public boolean insertAddRole(UserRidVo userRidVo) {
        byte[] bs1 = new byte[0];
        try {
            bs1 = MessageDigest.getInstance("md5").digest(userRidVo.getPassword().getBytes());
            userRidVo.setPassword(new BigInteger(1, bs1).toString(16));
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }
        User user = User.builder().account(userRidVo.getAccount())
                .password(userRidVo.getPassword())
                .uname(userRidVo.getUname())
                .age(userRidVo.getAge())
                .sex(userRidVo.getSex())
                .status(userRidVo.getStatus())
                .uphone(userRidVo.getUphone()).build();
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("account",user.getAccount());
        User user1 = userMapper.selectOne(query);
        if(Objects.isNull(user1)){
            this.save(user);
            userMapper.saveRoleForUserId(userRidVo.getRid(), user.getUid());
            return true;
//            for (Long rid : userRidVo.getRids()){
//                userMapper.saveRoleForUserId(rid, user.getUid());
//            }
//            return true;
        }
        return false;
    }

    /**
     * 删除用户，及其角色
     *
     * @param uid
     * @return
     */
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public boolean deleteAndRole(Long uid) {
        userMapper.updateLocalTime(uid);
        this.removeById(uid);
        userMapper.delRoleForUserId(uid);
        return true;
    }


    /**
     * 更改user表的修改时间为进行当前修改操作的时间
     * @param uid
     * @return
     */
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public boolean updateLocalTime(Long uid) {
        userMapper.updateLocalTime(uid);
        return true;
    }

    /**
     * 重置当前用户密码为88888888
     * @param uid
     * @return
     */
    @Override
    public boolean resetPassword(int uid) {
        String newPass = "88888888";
        byte[] bs1;
        try {
            bs1 = MessageDigest.getInstance("md5").digest(newPass.getBytes());
            newPass = new BigInteger(1, bs1).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return super.baseMapper.resetPassword(uid,newPass);
    }

    /**
     * 获取当前所有的角色名称
     * @return
     */
    @Override
    public List<Map<String, Object>> showAllRname() {
        return userMapper.showAllRname();
    }


    /**
     * 分页查询历史人员信息及其角色
     * @param pagination
     * @return
     */
    @Override
    public List<UserRoleNameVo> showHistoryUser(Page<UserRoleNameVo> pagination) {
        return userMapper.showHistoryUser(pagination);
    }


    public static void main(String[] args) {
        byte[] bs1 = new byte[0];
        String password = "123456";
        try {
            bs1 = MessageDigest.getInstance("md5").digest(password.getBytes());
            password = new BigInteger(1, bs1).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        System.out.println(password);
    }








}
